home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 140 / Gekkan Dennou Club - 2000.1 Vol. 140 (Japan).7z / Gekkan Dennou Club - 2000.1 Vol. 140 (Japan) (Track 1).bin / tools / dshell / dsh333bs.lzh / cutsub.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-05  |  11.7 KB  |  570 lines

  1. /*
  2.     dshell    v3
  3.  
  4.     CUTファイル表示関連
  5. */
  6.  
  7. #include    "dsh.h"
  8.  
  9.  
  10. static int expand1(uchar *, int, uchar *);
  11. static int expand2(uchar *, int, uchar *);
  12. static void nega_posi(uchar *, int, uchar);
  13.  
  14. static uchar loadingBgCutFlag = FALSE;
  15.  
  16. /*
  17.     1        総バイト数
  18.     BUF_X / 8    圧縮フラグのMAX
  19.     BUF_X        非圧縮部のビットパターンのMAX
  20. */
  21. typedef uchar CONDBUF[1 + BUF_X / 8 + BUF_X];
  22.  
  23.  
  24.  
  25. /*
  26.     CUTファイルのヘッダー読み込み
  27.  
  28.     戻り値:
  29.         必要なバッファサイズ(0の時はエラー)
  30. */
  31. int
  32. cut_read_header(FILE *fp, CUT *cut)
  33. {
  34.     short cut_size;
  35.     char cut_header[96];
  36.     char type;
  37.  
  38.     switch (cut->type) {
  39.     case CUTFILE:
  40.         if (fread(cut_header, sizeof(char), 48 + 2 + 2, fp) != 48 + 2 + 2) {
  41.             cut->type = -1;
  42.             return 0;
  43.         }
  44.         break;
  45.     case TITLESYS:
  46.         if (fread(cut_header, sizeof(char), 48 + 16 + 2 + 2, fp) != 48 + 16 + 2 + 2) {
  47.             cut->type = -1;
  48.             return 0;
  49.         }
  50.         break;
  51.     default:
  52.         cut->type = -1;
  53.         fread(cut_header, sizeof(char), 48, fp);    /* ヘッダー文字列読み込み */
  54.  
  55.         if (*cut_header == 0) {
  56.             fread(cut_header, sizeof(char), 16, fp);
  57.             type = TITLESYS;
  58. #if 0
  59.         } else if ((*cut_header == 'C') || (strncmp(cut_header, "CUT_V", 5) == 0)) {
  60. #else
  61.         } else if (*cut_header == 'C') {
  62. #endif
  63.             type = CUTFILE;
  64.         } else {
  65.             return 0;
  66.         }
  67.         fread(&cut_size, 2, 1, fp);
  68.         if (cut_size <= 0)
  69.             return 0;
  70.         cut->x = cut_size;    /* X方向ドット数(上位2バイト) */
  71.         fread(&cut_size, 2, 1, fp);
  72. #define    CUTLINEMAX    (0x7f - 0x20)
  73.         if (cut_size <= 0 || cut_size > CUTLINEMAX * 16)
  74.             return 0;
  75.         cut->y = cut_size;    /* Y方向ドット数(下位2バイト) */
  76.         cut->type = type;
  77.         break;
  78.     }
  79.  
  80.     return byteCount(cut->x) * cut->y    /* データ本体バッファサイズ */
  81.         + lineCount(cut->y) * 4;        /* 各行カット縦横サイズ格納分 */
  82. }
  83.  
  84. /*
  85.     カットファイル本体読み込み
  86.     (逐次読み込み、展開)
  87. */
  88. int 
  89. cut_read2(FILE *fp, CUT *cut)
  90. {
  91.     int size, y, by;    /* bit-Y */
  92.  
  93.     CONDBUF cond1, cond2;
  94.     uchar *buffer;
  95.     TEXTBUF *now_ptr;
  96.  
  97.     now_ptr = cut->ptr;
  98.     size = byteCount(cut->x);
  99.     /*
  100.         まず expand2内のバッファをクリアしておく
  101.         (一番最初のラインの一つ前のラインを疑似的に作る)
  102.         渡す buffer, cond2 はダミー
  103.     */
  104.     expand2(NULL, 0, NULL);
  105.  
  106.     for (y = 0, by = 0; y < cut->y; y++) {
  107.         if (by == 0) {
  108.             now_ptr->dx = cut->x;
  109.             now_ptr->dy = BUF_Y;
  110.             buffer = &now_ptr->buffer[0][0];
  111.         }
  112.         /*
  113.             先頭1バイト(圧縮後の1ラインの総バイト数)の
  114.             読み込みとチェック
  115.         */
  116.         if (fread(cond1, 1, 1, fp) < 1) {
  117.             break;
  118.         }
  119.         /*
  120.             続いて数バイトの圧縮フラグと、
  121.             非圧縮の部分のビットイメージデータ列の
  122.             読み込みとチェック
  123.         */
  124.         if (fread(cond1 + 1, sizeof(char), (*cond1) - 1, fp) < *cond1 - 1) {
  125.             break;
  126.         }
  127.  
  128.         expand1(cond2, size, cond1);
  129.         expand2(buffer, size, cond2);
  130.         buffer += size;
  131.         if (++by == BUF_Y) {
  132.             by = 0;
  133.             now_ptr = (TEXTBUF *) buffer;
  134.         }
  135.     }
  136.     if (by != 0) {
  137.         now_ptr->dy = by;
  138.     }
  139.     return 0;
  140. }
  141.  
  142.  
  143. /*
  144.     カットファイル本体読み込み
  145.     (一括読み込み後の展開)
  146. */
  147. int 
  148. cut_read(char *cut_ptr2, CUT *cut)    /* TEXTBUF *cut_ptr, int cut_x, int cut_y) */
  149. {
  150.     int size, y, by;
  151.  
  152.     CONDBUF cond2;
  153.     char *cond1;
  154.     uchar *buffer;
  155.     TEXTBUF *now_ptr;
  156.  
  157.     cond1 = cut_ptr2;
  158.     now_ptr = cut->ptr;
  159.     size = byteCount(cut->x);
  160.     /*
  161.         expand2()内のバッファ初期化
  162.         渡す buffer, cond2 はダミー
  163.     */
  164.     expand2(NULL, 0, NULL);
  165.     for (y = 0, by = 0; y < cut->y; y++) {
  166.         if (by == 0) {
  167.             now_ptr->dx = cut->x;
  168.             now_ptr->dy = BUF_Y;
  169.             buffer = &now_ptr->buffer[0][0];
  170.         }
  171.         expand1(cond2, size, cond1);
  172.         expand2(buffer, size, cond2);
  173.         buffer += size;
  174.         if (++by == BUF_Y) {
  175.             by = 0;
  176.             now_ptr = (TEXTBUF *) buffer;
  177.         }
  178.         cond1 += *cond1;
  179.     }
  180.     if (by != 0) {
  181.         now_ptr->dy = by;
  182.     }
  183.     return 0;
  184. }
  185.  
  186. /*
  187.     TITLE.SYSフォーマットデータ
  188.     (逐次読み込み、展開)
  189. */
  190. int 
  191. ttl_read2(FILE *fp, CUT *cut)    /* TEXTBUF *cut_ptr, int cut_x, int cut_y) */
  192. {
  193.     int size, y, by;
  194.     uchar *buffer;
  195.     TEXTBUF *now_ptr;
  196.  
  197.     now_ptr = cut->ptr;
  198.     size = byteCount(cut->x);
  199.     for (y = 0, by = 0; y < cut->y; y++) {
  200.         if (by == 0) {
  201.             now_ptr->dx = cut->x;
  202.             now_ptr->dy = BUF_Y;
  203.             buffer = &now_ptr->buffer[0][0];
  204.         }
  205.         if (fread(buffer, sizeof(char), size, fp) < size) {
  206.             break;
  207.         }
  208.  
  209.         buffer += size;
  210.         if (++by == BUF_Y) {
  211.             by = 0;
  212.             now_ptr = (TEXTBUF *) buffer;
  213.         }
  214.     }
  215.     if (by != 0) {
  216.         now_ptr->dy = by;
  217.     }
  218.     return 0;
  219. }
  220.  
  221.  
  222. /*
  223.     TITLE.SYSフォーマットデータ
  224.     (一括読み込み後の展開)
  225. */
  226. int 
  227. ttl_read(char *cut_ptr2, CUT *cut)    /* TEXTBUF *cut_ptr, int cut_x, int cut_y) */
  228. {
  229.     int size, x, y, by;
  230.     char *cond1;
  231.     uchar *buffer;
  232.     TEXTBUF *now_ptr;
  233.  
  234.     cond1 = cut_ptr2;
  235.     now_ptr = cut->ptr;
  236.     size = byteCount(cut->x);
  237.     for (y = 0, by = 0; y < cut->y; y++) {
  238.         if (by == 0) {
  239.             now_ptr->dx = cut->x;
  240.             now_ptr->dy = BUF_Y;
  241.             buffer = &now_ptr->buffer[0][0];
  242.         }
  243.         for (x = 0; x < size; x++) {
  244.             *buffer++ = *cond1++;
  245.         }
  246.         if (++by == BUF_Y) {
  247.             by = 0;
  248.             now_ptr = (TEXTBUF *) buffer;
  249.         }
  250.     }
  251.     if (by != 0) {
  252.         now_ptr->dy = by;
  253.     }
  254.     return 0;
  255. }
  256.  
  257.  
  258. /*
  259.     圧縮フラグによるデータ展開
  260.  
  261.     org:元データ
  262.     cond:展開後データ
  263.     count:展開後のデータの大きさ
  264. */
  265. static int 
  266. expand1(uchar *org, int count, uchar *cond)
  267. {
  268.     int pt, bt, flag;
  269.     uchar *head, *body;
  270.  
  271.     if (*cond == 1) {    /* 全圧縮の時 */
  272.         for (pt = 0; pt < count; pt++) {
  273.             *org++ = 0;
  274.         }
  275.         return (count);
  276.     }
  277.     pt = byteCount(count);
  278.     body = (head = cond + 1) + pt;    /* ビットイメージデータのポインタセット */
  279.     for (; pt; pt--) {
  280.         flag = *head++;
  281.         for (bt = 8; bt; bt--) {
  282.             if (flag & 0x80) {
  283.                 *org = *body++;    /* 非圧縮データ */
  284.             } else {
  285.                 *org = 0;    /* 圧縮データ */
  286.             }
  287.             org++;
  288.             flag <<= 1;
  289.         }
  290.     }
  291.     return count;
  292. }
  293.  
  294. /*
  295.     XORによる展開
  296.  
  297.     org:展開後データ
  298.     cond:元データ
  299.     count:データの大きさ
  300. */
  301. static int 
  302. expand2(uchar *org, int count, uchar *cond)
  303. {
  304.     static LINEBUF org_buf;
  305.     int c;
  306.     uchar *buf;
  307.  
  308.     buf = org_buf;
  309.     if (count == 0) {        /* バッファの初期化(init)指定 */
  310.         for (c = 0; c < BUF_X; c++) {
  311.             *buf++ = 0;
  312.         }
  313.     } else {            /* 実際にデータ展開 */
  314.         for (c = 0; c < count; c++) {
  315.             *org = *cond++ ^ *buf;    /* 前ラインの対応ビットとのXOR */
  316.             *buf++ = *org++;
  317.         }
  318.     }
  319.     return count;
  320. }
  321.  
  322. void 
  323. d_cut_load(char *filnm)
  324. {
  325.     w_mes(0, "カットファイルをロード中です");
  326.     w_mes(1, filnm);
  327.     w_mes(2, "しばらくお待ち下さい");
  328.     /*
  329.     !    w_mes(3,"                                    ");
  330.     !    w_mes(4,Sysmes2);
  331.     !    w_mes(5,"  + cut_file Loader ver1.0 By BEEPs ");
  332.     */
  333. }
  334.  
  335. int 
  336. cut_print(int sx, int sy, CUT *cut, int cut_lno)
  337. {
  338.     int x = 0, size;
  339.     uchar *ptr;
  340.  
  341.     if (cut->ptr != NULL && cut_lno < lineCount(cut->y)) {
  342.         uchar mask = 0;
  343.         static const uchar maskPat[] = {
  344.             0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01,
  345.         };
  346.  
  347.         if (cutrev_Mode && (cut->flag & cutREVERSE))
  348.             mask = maskPat[cut->x & (8 - 1)];
  349.         x = byteCount(cut->x);
  350.         size = x * BUF_Y;
  351.         ptr = (uchar *)cut->ptr + (size + 4) * cut_lno;
  352.         if (mask) {    /* ハードコピー用に陰陽反転 */
  353.             nega_posi(ptr + 4, x, mask);
  354.         }
  355.         TEXTPUT(sx, sy, (struct FNTBUF *)ptr);
  356.         if (mask) {    /* 反転を戻す */
  357.             nega_posi(ptr + 4, x, mask);
  358.         }
  359.     }
  360.     return x;
  361. }
  362.  
  363. /*
  364.     陰陽反転表示のため、カットデータバッファの内容をビット反転する(一行分)
  365.  
  366.     x:横バイト数
  367. */
  368. static void
  369. nega_posi(uchar *ptr, int x, uchar maskpat)
  370. {
  371.     int i, j;
  372.  
  373.     for (j = 0; j < BUF_Y; j++) {
  374.         for (i = 1; i < x; i++) {
  375.             *ptr++ ^= 0xff;
  376.         }
  377.         *ptr++ = *ptr ^ maskpat;
  378.     }
  379. }
  380.  
  381.  
  382. /*
  383.     カットファイルを読み込み
  384.     データを内部バッファに展開する
  385.  
  386.     cut_no:カットファイル(名)バッファの格納開始番号(ポインタ:0~)
  387. */
  388. int 
  389. cut_job_read(int cut_no)
  390. {
  391.     FILE *fp;
  392.     int cut_size;
  393.     char *cut_ptr2;        /* 一気読込モード時のバッファポインタ */
  394.     int cut_first, cut_last;
  395.  
  396.     cut_first = cut_no;    /* これから読むカットデータはここから… */
  397.     for (cut_last = cut_no; cut_last < CUT_MAX && cut[cut_last].fname != NULL; cut_last++) ;    /* …ここまで */
  398.  
  399.     for (; cut_no < CUT_MAX && cut[cut_no].fname != NULL; cut_no++) {
  400.         if (!loadingBgCutFlag) {
  401.             char mes[16];
  402.  
  403.             d_cut_load(cut[cut_no].fname);
  404.  
  405.             sprintf(mes, "%3d / %3d", cut_no - cut_first + 1, cut_last - cut_first);
  406.             w_mes(3, mes);
  407.         }
  408.         cut[cut_no].ptr = NULL;
  409.         if ((fp = fopen(cut[cut_no].fname, "rb")) == NULL) {
  410.             if (!loadingBgCutFlag) {
  411.                 char bf[100];
  412.  
  413.                 w_open();
  414.                 sprintf(bf, "%sがオープンできません", cut[cut_no].fname);
  415.                 w_mes(0, bf);
  416.                 w_mes(2, "処理を続けます");
  417.                 w_wait(100);
  418.             }
  419.             continue;
  420.         }
  421.         if ((cut_size = cut_read_header(fp, &(cut[cut_no]))) > 0) {
  422.             cut[cut_no].ptr = (TEXTBUF *)MALLOC(cut_size);
  423.             if ((int)cut[cut_no].ptr < 0) {
  424.                 cut[cut_no].ptr = NULL;
  425.             } else {
  426.                 cut_size = dfilelength(fileno(fp));
  427.                 cut_ptr2 = (char *)MALLOC(cut_size);
  428.                 if ((int)cut_ptr2 < 0) {
  429.                     if (cut[cut_no].type == TITLESYS) {
  430.                         ttl_read2(fp, &(cut[cut_no]));
  431.                     } else if (cut[cut_no].type == CUTFILE) {
  432.                         cut_read2(fp, &(cut[cut_no]));
  433.                     }
  434.                 } else {
  435.                     fread(cut_ptr2, sizeof(char), cut_size, fp);
  436.                     if (cut[cut_no].type == TITLESYS) {
  437.                         ttl_read(cut_ptr2, &(cut[cut_no]));
  438.                     } else if (cut[cut_no].type == CUTFILE) {
  439.                         cut_read(cut_ptr2, &(cut[cut_no]));
  440.                     }
  441.                     if (MFREE(cut_ptr2) && !loadingBgCutFlag) {
  442.                         d_mfree();
  443.                     }
  444.                 }
  445.             }
  446.         }
  447.         fclose(fp);
  448.     }
  449.  
  450.     return (cut_no);
  451. }
  452.  
  453.  
  454. /*
  455.     CUT ファイル名の解釈と対応する CUT 番号の取得
  456. */
  457. int
  458. getCutNo(uchar *p, uchar *cutPath, struct NAMECKBUF *fname, uchar **tail, uchar termChr)
  459. {
  460.     uchar pflag = FALSE;
  461.     uchar hflag = FALSE;
  462.     uchar nflag = cutREVERSE;
  463.     uchar dupFlag = FALSE;
  464.     uchar c, cbak, *q = p;
  465.     signed char alignMode = 0;
  466.     int n;
  467.  
  468.     while ((c = *q++) > ' ' && c != termChr)
  469.         ;
  470.     q--;
  471.     cbak = *q;
  472.     *q = '\0';
  473.     while (c = *p++) {
  474.         if (c == '+')        // ドキュメントファイルと同一パスから探す
  475.             pflag = TRUE;
  476.         else if (c == '-')    // カットファイル名を表示しない
  477.             hflag = TRUE;
  478.         else if (c == '*')    // イメージ印刷の際ネガポジ反転しない
  479.             nflag = 0;
  480.         else if (c == '?') {    // 必要行数の %CUT を自動挿入する
  481.             dupFlag = cutDUP;
  482.             hflag = TRUE;
  483.         } else if (c == '<') {    // 左寄せ
  484.             alignMode = -1;
  485.             dupFlag = FALSE;
  486.             hflag = TRUE;
  487.         } else if (c == '>') {    // 右寄せ
  488.             alignMode = 1;
  489.             dupFlag = FALSE;
  490.             hflag = TRUE;
  491.         } else
  492.             break;
  493.     }
  494.     if (c == '\0' || NAMECK(--p, fname) != 0) {
  495.         *q = cbak;
  496.         return -1;
  497.     }
  498.     if (pflag) {
  499.         char temp[256];
  500.         strcpy(temp, cutPath);
  501.         strcat(temp, p);
  502.         NAMECK(temp, fname);
  503.     }
  504.     *q = cbak;
  505.     if (hflag && tail != NULL) {
  506.         if (cbak == termChr)
  507.             q++;
  508.         *tail = q;
  509.     }
  510.     strcat((char *)fname, fname->name);
  511.     strcat((char *)fname, fname->ext);
  512.     dstrupr((char *)fname);
  513.  
  514.     for (n = 0; n < CUT_MAX; n++) {
  515.         if (cut[n].fname == NULL) {
  516.             FILE *fp;
  517.  
  518.             cut[n].flag = (nflag | dupFlag);
  519.             if (alignMode < 0)
  520.                 cut[n].flag |= cutLEFT;
  521.             else if (alignMode > 0)
  522.                 cut[n].flag |= cutRIGHT;
  523.             cut[n].type = -1;
  524.             cut[n].fname = (char *)fname;
  525.             if ((fp = fopen((char *)fname, "rb")) != NULL) {
  526.                 // ヘッダを読み、サイズを得る
  527.                 cut_read_header(fp, &cut[n]);
  528.                 fclose(fp);
  529.             }
  530.             if (tail == NULL)
  531.                 cut[n].flag &= cutREVERSE;
  532.             cut[n].fname = NULL;
  533.             return n;
  534.         } else if (((cut[n].flag & nflag) == nflag) && cut[n].type >= 0
  535.           && strEqu(cut[n].fname, (char *)fname)) {
  536.             if (tail != NULL)
  537.                 cut[n].flag |= dupFlag;
  538.             if (alignMode < 0)
  539.                 cut[n].flag |= cutLEFT;
  540.             else if (alignMode > 0)
  541.                 cut[n].flag |= cutRIGHT;
  542.             return n;
  543.         }
  544.     }
  545.  
  546.     dabort("カットファイル数が最大値を越えます");
  547.     return -1;
  548. }
  549.  
  550.  
  551. int
  552. loadBgCut(uchar *fname)
  553. {
  554.     struct NAMECKBUF temp;
  555.  
  556.     loadingBgCutFlag = TRUE;    // メッセージウィンドウの抑制
  557.     if (getCutNo(fname, ((struct PDBADR *)_PSP)->exe_path, &temp, NULL, ';') < 0)
  558.         return -1;
  559.     if ((fname = strdup(fname)) == NULL)
  560.         return -1;
  561.     cut[0].fname = fname;
  562.     cut_job_read(Cut_Begin);
  563.     if (cut[0].ptr == NULL)
  564.         return -1;
  565.     Cut_Begin++;
  566.     loadingBgCutFlag = FALSE;
  567.  
  568.     return 0;
  569. }
  570.